/*
 * @Author       : NaN 353362604@qq.com
 * @Date         : 2023-04-19 09:47:06
 * @LastEditTime : 2023-06-25 14:25:13
 * @LastEditors  : NaN 353362604@qq.com
 * @FilePath     : \AdminStration\src\Pages\Front\Common\Mars3d\MechanicalTrajectory.jsx
 * @Description  :
 */

import './index.scss'
import { message, Tooltip, Modal, Select, Card, Calendar, Badge, TimePicker, Button } from 'antd'
import { useBoolean, useEventEmitter, useRequest, useSize } from 'ahooks'
import { Http } from '../../../../Common/Api'
import { Initialization, InitializationData } from '../../../../Common/Mars3d/Initialization'
import { useEffect, useState, useRef } from 'react'
import { ICON } from '../../../../Common/Configure/Icon'
import { CommonSmallTitle } from '../../Common/Other/SmallTitle'
import { VideoCameraFilled, BorderlessTableOutlined, CloseCircleOutlined } from '@ant-design/icons'
import Draggable from 'react-draggable'
import { Video } from '../../../../Common/Configure/Video'
import { WebTemplateUrl } from '../Template/configuration'
import dayjs from 'dayjs'
const { mars3d, Cesium } = window
const { Meta } = Card
const CarModal = {
    '002': 'https://image.ljkjkf.com/intellisiteSystem_TieKe/BimModelFiles/gltf/che1.glb',
    '001': '//data.mars3d.cn/gltf/mars/car/zhatuche.glb',
}
const Interval = 30000

const ColorList = ['#ff4d4f', '#52c41a']

export const MechanicalTrajectory = ({ className, ScenesID, CarSelect, Status }) => {
    const { runAsync: getScenesDetails } = useRequest(Http, { manual: true })
    const { run: getScenes } = useRequest(Http, {
        manual: true,
        onSuccess: res => Initialization(res, Mars3dBox, InitializationEvent),
    })
    const { runAsync: getMachineManageGetOneMachineInfo } = useRequest(Http, { manual: true })
    const { runAsync: getMachineManageGetImportantMachineOrgList } = useRequest(Http, { manual: true })

    const { runAsync: getMachineManageGetOneMachineNowGPSData } = useRequest(Http, {
        manual: true,
        pollingInterval: Interval,
        onSuccess: (res, params) => {
            const { list } = res
            const [{ gra }] = params
            setMechanicalData(list)
            list.forEach(item => {
                if (gra.getGraphicById(item.uuid)) {
                    gra.getGraphicById(item.uuid).addDynamicPosition(
                        Cesium.Cartesian3.fromDegrees(item.lng, item.lat, 30),
                        Interval / 1000,
                    )
                } else {
                    const graphic = new mars3d.graphic.PathEntity({
                        id: item.uuid,
                        style: {
                            width: 0,
                            opacity: 0,
                            color: '#000',
                            leadTime: 0,
                        },
                        label: {
                            text: item.tableName,
                            clampToGround: true,
                            visibleDepth: false,
                            pixelOffsetY: -30,
                            font_size: 18,
                            color: 'red',
                            font_family: '微软雅黑',
                            font_weight: 'bold ',
                            boderColor: '#15d1f2',
                            outline: true,
                            outlineColor: '#fff',
                            outlineWidth: 5,
                            show: true,
                        },
                        model: {
                            url: CarModal[CarSelect],
                            scale: 1,
                            minimumPixelSize: 50,
                            clampToGround: true,
                            silhouette: item.isNowDate,
                            silhouetteColor: '#41B883',
                        },
                    })
                    gra.addGraphic(graphic)
                    graphic.addDynamicPosition(Cesium.Cartesian3.fromDegrees(item.lng, item.lat, 30), 20)
                }
            })
        },
    })

    const Mars3dBox = useRef()
    const [Map, setMap] = useState()
    const [Gra, setGra] = useState()

    const InitializationEvent = useEventEmitter()
    InitializationEvent.useSubscription(({ map, gra, uuid }) => {
        setMap(map)
        setGra(gra)
        getScenesDetails({ url: `getScenesDetailsUuid`, path: [uuid] }).then(res => InitializationData(map, gra, res))
        getMachineManageGetOneMachineNowGPSData({ url: 'getMachineManageGetOneMachineNowGPSData', gra })
    })
    const [MechanicalData, setMechanicalData] = useState([])
    const [MechanicalActive, setMechanicalActive] = useState()
    const [MechanicalDataOne, setMechanicalDataOne] = useState()
    const [DetailsModalStatus, { setTrue, setFalse }] = useBoolean(false)
    const [MechanicalOrgList, setMechanicalOrgList] = useState([])
    const [MechanicalSelect, setMechanicalSelect] = useState()

    const OpenMechContent = uuid => {
        if (uuid !== MechanicalActive) {
            getMachineManageGetOneMachineInfo({
                url: 'getMachineManageGetOneMachineInfo',
                data: { MachineUuid: uuid },
            }).then(res => {
                const { list } = res
                if (list.length === 0) message.info('当前机械暂无数据')
                else {
                    const [data] = list
                    setMechanicalDataOne(data)
                    setMechanicalActive(uuid)
                }
            })
        }
    }

    const positioningFunc = data => {
        if (data.isGps === 0) {
            message.info('当前车辆暂无GPS信息')
            return false
        }
        Map.flyToPoint(Gra.getGraphicById(data.uuid).positionShow, { radius: 5000, heading: 143, pitch: -28 })
    }

    const liveBroadcastFunc = data => {
        if (data.isCamera === 0) {
            message.info('当前车辆暂无监控视频')
            return false
        }
        setMechanicalSelect({ ...data, OpenType: 'live' })
        setTrue()
    }

    const trajectoryFunc = data => {
        if (data.isHistoryDate === 0) {
            message.info('当前车辆暂无轨迹信息')
            return false
        }
        setMechanicalSelect({ ...data, OpenType: 'trace' })
        setTrue()
    }

    useEffect(() => {
        getScenes({ url: `getScenesID`, path: [ScenesID] })
    }, [ScenesID, getScenes])

    useEffect(() => {
        getMachineManageGetImportantMachineOrgList({ url: 'getMachineManageGetImportantMachineOrgList' }).then(res =>
            setMechanicalOrgList(res.list),
        )
    }, [getMachineManageGetImportantMachineOrgList])

    return (
        <div className="MechanicalTrajectory">
            <div className="MechanicalTrajectoryMap" ref={Mars3dBox}></div>
            <img className="Mask" src={WebTemplateUrl + 'Mask.png'} alt="" />
            <div
                className={`MechanicalTrajectoryList animate__animated ${
                    Status ? 'animate__backInRight' : 'animate__backOutRight'
                }`}
            >
                <CommonSmallTitle className={className} title="机械列表" flex={63}>
                    <div className="ALL">
                        <Button type="primary" onClick={() => setTrue()}>
                            查看详情
                        </Button>
                    </div>
                    <div className="List">
                        {MechanicalData.map(({ uuid, tableName, organizationName, machineCode }) => (
                            <div className="Box" key={uuid} onClick={() => OpenMechContent(uuid)}>
                                <div className="Title">
                                    {organizationName}({machineCode}){tableName}
                                </div>
                                {MechanicalActive === uuid && (
                                    <div className="Content">
                                        <div className="Options">
                                            <Tooltip title="当前位置">
                                                <span
                                                    onClick={() => positioningFunc(MechanicalDataOne)}
                                                    style={{ color: ColorList[MechanicalDataOne.isGps] }}
                                                >
                                                    {ICON['IconDingweixiao']}
                                                </span>
                                            </Tooltip>
                                            <Tooltip title="现场画面">
                                                <span
                                                    onClick={() => liveBroadcastFunc(MechanicalDataOne)}
                                                    style={{ color: ColorList[MechanicalDataOne.isCamera] }}
                                                >
                                                    {ICON['Iconhome23']}
                                                </span>
                                            </Tooltip>
                                            <Tooltip title="历史轨迹">
                                                <span
                                                    style={{ color: ColorList[MechanicalDataOne.isHistoryDate] }}
                                                    onClick={() => trajectoryFunc(MechanicalDataOne)}
                                                >
                                                    {ICON['IconDaqia']}
                                                </span>
                                            </Tooltip>
                                        </div>
                                        <div className="Text">
                                            <div className="one">
                                                <div>机械名称:</div> <div> {MechanicalDataOne.tableName} </div>
                                            </div>
                                            <div className="one">
                                                <div>司机姓名:</div> <div> {MechanicalDataOne.driverName} </div>
                                            </div>
                                            <div className="one">
                                                <div>机械编号:</div> <div> {MechanicalDataOne.code} </div>
                                            </div>
                                            <div className="one">
                                                <div>联系方式:</div> <div> {MechanicalDataOne.driverMobile} </div>
                                            </div>
                                            <div className="one">
                                                <div>标段名称:</div> <div> {MechanicalDataOne.organizationName} </div>
                                            </div>
                                            <div className="all">
                                                <div>机械类型:</div> <div> {MechanicalDataOne.machineTypeName} </div>
                                            </div>
                                            <div className="all">
                                                <div>进场时间:</div> <div> {MechanicalDataOne.entryTime} </div>
                                            </div>
                                            <div className="all">
                                                <div>机械位置:</div> <div> {MechanicalDataOne.address} </div>
                                            </div>
                                        </div>
                                    </div>
                                )}
                            </div>
                        ))}
                    </div>
                </CommonSmallTitle>
            </div>
            {DetailsModalStatus && (
                <MechanicalTrajectoryModal
                    className={className}
                    ScenesID={ScenesID}
                    CarSelect={CarSelect}
                    Off={setFalse}
                    MechanicalOrgList={MechanicalOrgList}
                    MechanicalSelect={MechanicalSelect}
                />
            )}
        </div>
    )
}

const MechanicalTrajectoryModal = ({ Off, ScenesID, CarSelect, className, MechanicalOrgList, MechanicalSelect }) => {
    const Mars3dBox = useRef()
    const DraggableBox = useRef()
    const size = useSize(DraggableBox)

    const [Map, setMap] = useState()
    const [Gra, setGra] = useState()
    const { run: getScenes } = useRequest(Http, {
        manual: true,
        onSuccess: res => Initialization(res, Mars3dBox, InitializationEvent),
    })
    const { runAsync: getScenesDetails } = useRequest(Http, { manual: true })
    const { runAsync: getMachineManageGetMachineListByOrg } = useRequest(Http, { manual: true })
    const { runAsync: getMachineManageGetOneMachineTraceCalendars } = useRequest(Http, { manual: true })
    const { runAsync: getMachineManageGetOneMachineTrace } = useRequest(Http, { manual: true })
    const [SelectValue, setSelectValue] = useState()
    const [SelectDataList, setSelectDataList] = useState([])

    const InitializationEvent = useEventEmitter()
    InitializationEvent.useSubscription(({ map, gra, uuid }) => {
        setMap(map)
        setGra(gra)
        getScenesDetails({ url: `getScenesDetailsUuid`, path: [uuid] }).then(res => InitializationData(map, gra, res))
    })

    const SelectChange = e => {
        if (e !== ActiveUuid) {
            VideoFalse()
            HistoryFalse()
            setYearValue(dayjs().format('YYYY'))
            setMonthValue(dayjs().format('MM'))
            setBeginTime(dayjs('00:00:00', 'HH:mm:ss'))
            setEndTime(dayjs('23:59:59', 'HH:mm:ss'))
            getMachineManageGetMachineListByOrg({
                url: 'getMachineManageGetMachineListByOrg',
                data: { organizationUuid: e },
            }).then(res => {
                const { list } = res
                setSelectDataList(list)
                setSelectValue(e)
            })
        }
    }

    const [ActiveUuid, setActiveUuid] = useState()
    const [VideoStatus, { setTrue: VideoTrue, setFalse: VideoFalse }] = useBoolean()
    const [HistoryStatus, { setTrue: HistoryTrue, setFalse: HistoryFalse }] = useBoolean()
    const [VideoData, setVideoData] = useState()

    const OpenCamera = data => {
        setVideoData(data)
        if (VideoStatus) VideoFalse()
        else VideoTrue()
    }

    const OpenHistory = data => {
        if (data.uuid !== ActiveUuid) {
            setActiveUuid(data.uuid)
            getDate(data.uuid, dayjs().format('YYYY-MM'))
        }
    }

    const getDate = (uuid, date) => {
        getMachineManageGetOneMachineTraceCalendars({
            url: 'getMachineManageGetOneMachineTraceCalendars',
            data: { MachineUuid: uuid, YearMonth: date },
        }).then(res => {
            const { list, list1 } = res
            const dayList = list.map(item => Number(item.traceDate))
            const monthList = list1.map(item => Number(item.traceDate))
            setDayList(dayList)
            setMonthList(monthList)
            HistoryTrue()
        })
    }

    useEffect(() => {
        getScenes({ url: `getScenesID`, path: [ScenesID] })
    }, [ScenesID, getScenes])

    const [DayList, setDayList] = useState([])
    const [MonthList, setMonthList] = useState([])

    const [DateValue, setDateValue] = useState(dayjs())
    const [YearValue, setYearValue] = useState(dayjs().format('YYYY'))
    const [MonthValue, setMonthValue] = useState(dayjs().format('MM'))

    const [BeginTimes, setBeginTime] = useState(dayjs('00:00:00', 'HH:mm:ss'))
    const [EndTime, setEndTime] = useState(dayjs('23:59:59', 'HH:mm:ss'))

    const CalendarChange = e => {
        const year = e.year()
        const month = e.month() + 1
        setDateValue(e)
        setYearValue(year)
        setMonthValue(month)
        if (Number(YearValue) !== year || (Number(MonthValue) !== month && MonthList.includes(month))) {
            getDate(ActiveUuid, dayjs(e).format('YYYY-MM'))
        }
    }

    const dateCellRender = e => {
        const date = e.date()
        const month = e.month() + 1
        return DayList.indexOf(date) !== -1 && month === Number(MonthValue) ? <Badge status="success" /> : null
    }

    const monthCellRender = e => {
        const year = e.year()
        const month = e.month() + 1
        return MonthList.indexOf(month) !== -1 && year === Number(YearValue) ? <Badge status="success" /> : null
    }

    const cellRender = (current, info) => {
        if (info.type === 'date') return dateCellRender(current)
        if (info.type === 'month') return monthCellRender(current)
        return info.originNode
    }

    const getTrace = () => {
        const date = dayjs(DateValue).format('YYYY-MM-DD')
        const data = {
            machineUuid: ActiveUuid,
            BeginTime: `${date} ${dayjs(BeginTimes).format('HH:mm:ss')}`,
            EndTime: `${date} ${dayjs(EndTime).format('HH:mm:ss')}`,
        }
        getMachineManageGetOneMachineTrace({
            url: 'getMachineManageGetOneMachineTrace',
            data,
        }).then(res => {
            const { list } = res
            if (list.length === 0) {
                message.info('当前时段没有历史轨迹')
                return false
            }
            if (Gra.getGraphicById(ActiveUuid)) {
                Gra.removeGraphic(Gra.getGraphicById(ActiveUuid), true)
                Gra.removeGraphic(Gra.getGraphicById(`route-${ActiveUuid}`), true)
            }

            let linePosition = []
            const property = new Cesium.SampledPositionProperty()
            property.forwardExtrapolationType = Cesium.ExtrapolationType.HOLD
            let start
            let stop
            for (let i = 0, len = list.length; i < len; i++) {
                const item = list[i]
                const lng = Number(item.lng)
                const lat = Number(item.lat)
                const height = 220
                const time = dayjs(item.deviceDate).format()
                linePosition = [...linePosition, [Number(item.lng), Number(item.lat), 0]]
                let position = null
                let juliaDate = null
                if (lng && lat) position = Cesium.Cartesian3.fromDegrees(lng, lat, height)
                if (time) juliaDate = Cesium.JulianDate.fromIso8601(time)
                if (position && juliaDate) property.addSample(juliaDate, position)
                if (i === 0) {
                    start = juliaDate
                } else if (i === len - 1) {
                    stop = juliaDate
                }
            }

            // 设置时钟属性
            Map.clock.startTime = start.clone()
            Map.clock.stopTime = stop.clone()
            Map.clock.currentTime = start.clone()
            Map.clock.clockRange = Cesium.ClockRange.LOOP_STOP
            Map.clock.multiplier = 100
            if (Map.controls.timeline) Map.controls.timeline.zoomTo(start, stop)
            // 创建path对象

            const lienData = new mars3d.graphic.PolylineEntity({
                id: `route-${ActiveUuid}`,
                positions: linePosition,
                style: { width: 3, color: '#ff0000', opacity: 0.3, clampToGround: true },
            })

            const pathEntity = new mars3d.graphic.PathEntity({
                id: ActiveUuid,
                position: property,
                orientation: new Cesium.VelocityOrientationProperty(property),
                style: {
                    resolution: 1,
                    leadTime: 0,
                    trailTime: 86400,
                    color: 'rgba(0,0,0,0)',
                    width: 3,
                },
                label: {
                    text: data.tableName,
                    clampToGround: true,
                    visibleDepth: false,
                    pixelOffsetY: -30,
                    font_size: 18,
                    color: 'red',
                    font_family: '微软雅黑',
                    font_weight: 'bold ',
                    boderColor: '#15d1f2',
                    outline: true,
                    outlineColor: '#fff',
                    outlineWidth: 5,
                },
                model: {
                    url: CarModal[CarSelect],
                    clampToGround: true,
                    minimumPixelSize: 50,
                },
            })
            Map.trackedEntity = undefined
            Map.flyToPoint(pathEntity.positionShow, { radius: 3000, heading: 143, pitch: -28 })
            Gra.addGraphic(lienData)
            Gra.addGraphic(pathEntity)
        })
    }

    useEffect(() => {
        if (MechanicalSelect) {
            console.log(MechanicalSelect)
            const { OpenType, uuid, organizationUuid } = MechanicalSelect
            setActiveUuid(uuid)
            getMachineManageGetMachineListByOrg({
                url: 'getMachineManageGetMachineListByOrg',
                data: { organizationUuid },
            }).then(res => {
                const { list } = res
                setSelectDataList(list)
                setSelectValue(organizationUuid)
            })
            if (OpenType === 'live') {
                setVideoData(MechanicalSelect)
                VideoTrue()
            } else {
                HistoryTrue()
            }
        }
    }, [
        MechanicalSelect,
        VideoTrue,
        HistoryTrue,
        getMachineManageGetMachineListByOrg,
        getMachineManageGetOneMachineTraceCalendars,
    ])

    return (
        <Modal
            className="MechanicalTrajectoryModal"
            open={true}
            footer={null}
            maskClosable={false}
            onCancel={Off}
            destroyOnClose
            centered
            width={'90vw'}
        >
            <CommonSmallTitle className={className} title="机械详情" flex={63}>
                <div className="Content">
                    <div className="Left">
                        <Select
                            style={{ width: '100%' }}
                            fieldNames={{ label: 'tableName', value: 'uuid' }}
                            value={SelectValue}
                            options={MechanicalOrgList}
                            placeholder="请先选择标段"
                            onChange={SelectChange}
                        />
                        <div className="List">
                            {SelectDataList.map(item => {
                                const actions = [
                                    item.isCamera === 1 && (
                                        <VideoCameraFilled
                                            style={{ fontSize: 16 }}
                                            key="edit"
                                            onClick={() => OpenCamera(item)}
                                        />
                                    ),
                                    item.isHistoryDate === 1 && (
                                        <BorderlessTableOutlined
                                            style={{ fontSize: 16 }}
                                            key="ellipsis"
                                            onClick={() => OpenHistory(item)}
                                        />
                                    ),
                                ].filter(Boolean)

                                return (
                                    <Card key={item.uuid} actions={[...actions]}>
                                        <Meta title={item.tableName} />
                                    </Card>
                                )
                            })}
                        </div>
                    </div>
                    <div className="Right" ref={DraggableBox}>
                        <div className="MechanicalTrajectoryMap" ref={Mars3dBox} />

                        {VideoStatus && (
                            <div className="VideoBox">
                                <div className="Close" onClick={VideoFalse}>
                                    <CloseCircleOutlined />
                                </div>
                                <Video data={VideoData} date={new Date().getTime()} />
                            </div>
                        )}

                        {size && HistoryStatus && (
                            <Draggable bounds={{ top: 0, left: 0, bottom: 0, right: size.width - 352 }}>
                                <div className="AdditionalBox">
                                    <div className="DraggableTitle">轨迹日期筛选</div>
                                    <Calendar fullscreen={false} onChange={CalendarChange} cellRender={cellRender} />
                                    <TimePicker.RangePicker
                                        value={[BeginTimes, EndTime]}
                                        allowClear={false}
                                        onChange={e => {
                                            const [state, end] = e
                                            setBeginTime(dayjs(state, 'HH:mm:ss'))
                                            setEndTime(dayjs(end, 'HH:mm:ss'))
                                        }}
                                    />
                                    <Button type="primary" onClick={getTrace}>
                                        {' '}
                                        查询{' '}
                                    </Button>
                                </div>
                            </Draggable>
                        )}
                    </div>
                </div>
            </CommonSmallTitle>
        </Modal>
    )
}
